<template>
  <ZZDialog class="myself" title="属性编辑">
    <div>
      <ul class="toolbar">
        <li><i class="fa fa-location-arrow" title="定位" @click="onFlyTo"></i></li>
        <li><i class="fa fa-trash" title="删除" @click="onDelete"></i></li>
        <li><i class="fa fa-save" title="保存文件" @click="onSave"></i></li>
        <input id="input_plot_file" type="file" accept=".json" style="display: none" />
      </ul>
    </div>
    <el-tabs v-model="activeName" class="demo-tabs" tab-position="bottom">
      <el-tab-pane class="tab-context" label="属性" name="first">
        <DSubTable v-model="attrRef"></DSubTable>
      </el-tab-pane>
      <el-tab-pane class="tab-context" label="坐标" name="second">
        <table table border="1" cellspacing="0" cellpadding="0">
          <template v-for="(item, index) in lonlatRef" :key="index">
            <tr>
              <td class="tb-content" colspan="2">第{{ index + 1 }}点</td>
            </tr>
            <tr>
              <td class="tb-content">经度</td>
              <td class="tb-content">
                <el-input-number v-model="item.lon" size="small" :step="0.00001" controls-position="right" />
              </td>
            </tr>
            <tr>
              <td class="tb-content">纬度</td>
              <td class="tb-content">
                <el-input-number v-model="item.lat" size="small" :step="0.00001" controls-position="right" />
              </td>
            </tr>
            <tr>
              <td class="tb-content">高度</td>
              <td class="tb-content">
                <el-input-number v-model="item.height" size="small" :step="1.0" controls-position="right" />
              </td>
            </tr>
          </template>
        </table>
      </el-tab-pane>
      <el-tab-pane class="tab-context" label="样式" name="third">
        <DSubTable v-model="styleRef"></DSubTable>
      </el-tab-pane>
    </el-tabs>
  </ZZDialog>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch } from 'vue';
import ZZDialog from '@/common/ZZDialog.vue';
import { useViewer, useDrawcontrol } from '@/stores/viewer';
import { attrConfig } from './plotData/attrConfig';
import EventBus from '@/common/EventBus';

import DSubTable from '@/common/DSubTable.vue';
import type { IAttrConfig } from '@/common/IDComponent';

let drawcontrol: any;
let currentEntity: any;

const activeName = ref('third');
type ILonlatData = {
  lon: number;
  lat: number;
  height: number;
};
const lonlatRef = ref<ILonlatData[]>([]);
const attrRef = ref<IAttrConfig[]>([]);
const styleRef = ref<IAttrConfig[]>([]);

const props = defineProps<{
  entity?: any;
  lonlats?: any;
}>();

const updateLonlat = function (lonlat: any, config: any = {}) {
  if (!lonlat) {
    return;
  }

  if (!config.hasOwnProperty('height')) {
    config.height = true;
  }

  lonlatRef.value.length = 0;
  lonlat.forEach((item: any) => {
    lonlatRef.value.push({
      lon: item[0],
      lat: item[1],
      height: item[2] || 0.0
    });
  });
};

const updateStyleShow = function () {
  const styles = styleRef.value;
  const impacts = []; // 所有需要控制的
  const showImpacts = []; // 需要显示的

  for (let i = 0; i < styles.length; ++i) {
    const item = styles[i];
    if (!item) continue;
    if (item.impact) {
      impacts.push(...item.impact);
      if (item.value == true) {
        showImpacts.push(...item.impact);
      }
    }
    if (item.data) {
      for (let j = 0; j < item.data.length; ++j) {
        const child = item.data[j];
        if (!child) continue;
        if (child.impact) {
          impacts.push(...child.impact);
          if (item.value == child.value) {
            showImpacts.push(...child.impact);
          }
        }
      }
    }
  }

  for (let i = 0; i < styles.length; ++i) {
    const item = styles[i];
    if (!item) continue;
    if (!impacts.includes(item.name) || showImpacts.includes(item.name)) {
      item.display = true;
    } else {
      item.display = false;
    }
  }

  return false;
};

const defaultAttrList = [
  { name: 'id', label: '主键', type: 'label', defval: '' },
  { name: 'name', label: '名称', type: 'text', defval: '' },
  { name: 'remark', label: '备注', type: 'textarea', defval: '' }
];

const updateAttr = function (config: any, attr: any) {
  const arrConfig = config.attrList || defaultAttrList;
  attrRef.value.length = 0;
  for (let i = 0; i < arrConfig.length; ++i) {
    const edit = arrConfig[i];
    if (edit.type == 'hidden') continue;

    const attrName = edit.name;
    const attrVal = attr.attr[attrName] || '';
    attrRef.value.push({
      name: edit.name,
      type: edit.type,
      label: edit.label,
      value: attrVal
    });
  }
};

const updateStyle = function (config: any, attr: any) {
  styleRef.value.length = 0;
  for (let idx = 0; idx < config.style.length; idx++) {
    const edit = config.style[idx];
    if (edit.type == 'hidden') continue;

    const attrName = edit.name;
    const attrVal = attr.style[attrName] ?? edit.defval;
    styleRef.value.push({
      name: edit.name,
      type: edit.type,
      label: edit.label,
      value: attrVal,
      data: edit.data,
      impact: edit.impact
    });
  }
};

watch(
  lonlatRef,
  newValue => {
    const positions = [];
    for (let i = 0; i < newValue.length; ++i) {
      const item = newValue[i];
      if (!item) continue;
      const pt = Cesium.Cartesian3.fromDegrees(Number(item.lon), Number(item.lat), Number(item.height));
      positions.push(pt);
    }
    drawcontrol.setPositions(positions);
  },
  { deep: true }
);

watch(
  attrRef,
  newValue => {
    const config = Object.assign({}, currentEntity.attribute);
    const attr = config.attr;
    for (let i = 0; i < newValue.length; ++i) {
      const item = newValue[i];
      if (!item) continue;
      attr[item.name] = item.value;
    }
    drawcontrol.updateAttribute(config);
  },
  { deep: true }
);

watch(
  styleRef,
  newValue => {
    const config = Object.assign({}, currentEntity.attribute);
    const style = config.style;
    for (let i = 0; i < newValue.length; ++i) {
      const item = newValue[i];
      if (!item) continue;
      style[item.name] = item.value;
    }
    drawcontrol.updateAttribute(config);
    updateStyleShow();
  },
  { deep: true }
);

const onDelete = function () {
  if (currentEntity) {
    drawcontrol.deleteEntity(currentEntity);
  }
};

const onFlyTo = function () {
  const viewer: any = useViewer().viewer;
  if (currentEntity) {
    //参数解释：线面数据：scale控制边界的放大比例，点数据：radius控制视距距离
    viewer.zz.flyTo(currentEntity, { scale: 0.5, radius: 1000 });
  }
};

const onSave = function () {
  if (currentEntity) {
    let context = zz3d.draw.attr.toGeoJSON(currentEntity);
    context = JSON.stringify(context);
    zz3d.util.downloadFile('标绘.json', context);
  }
};

const edit = function (opt: any) {
  currentEntity = opt.entity;
  const attr = opt.entity.attribute;
  const lonlat = opt.lonlats;
  const config = attrConfig[attr.edittype || attr.type] || {};
  config.style = config.style || {};

  updateLonlat(lonlat, config.points);
  updateStyle(config, attr);
  updateStyleShow();
  updateAttr(config, attr);
};

// 初始化调用
onMounted(async () => {
  drawcontrol = useDrawcontrol().drawcontrol;
  attrConfig['curve'] = attrConfig['polyline'];
  edit(props);
  EventBus.on('editEntity', edit);
});
</script>
<style scoped>
.myself {
  position: absolute;
  left: 10px;
  top: 420px;
  min-width: 100px;
  width: 230px;
  height: 400px;
}

.tab-context {
  height: 280px;
  overflow-y: auto;
}
</style>

<style scoped src="./toolbar.css"></style>
